#include "head.h"

//服务端ls实现代码
int ls_handler(client_info_t* pclient_info, MYSQL* mysql){
    user_t user;
    select_user(mysql,pclient_info->name,&user);
    int file_id = user.file_id;

    char query[256] = {0};  //用来放SQL语句的字符串
    MYSQL_RES *result;
    MYSQL_ROW row;

    //在file表找parent_id==file_id and cancel_flag==0(文件未被删除)的行
    sprintf(query,"select file_name from file where parent_id = %d and cancel_flag = 0",file_id);
    if(mysql_query(mysql,query)){
        fprintf(stderr,"query error:%s\n",mysql_error(mysql));
        return -1;
    }
    //接收处理结果集
    result = mysql_store_result(mysql);
    ERROR_CHECK(result,NULL,"mysql_store_result");

    char file_name[4096]={0};
    int file_name_len = 0;
    //获得行数
    int res_rows = mysql_num_rows(result);
    //如果行数为零(文件夹为空)
    if(res_rows == 0){
        strcpy(file_name,"什么都没有找到\n");
        file_name_len = strlen(file_name);
        printf("-------  %s\n", file_name);
        send(pclient_info->net_fd,&file_name_len,sizeof(int),MSG_NOSIGNAL);
        send(pclient_info->net_fd,file_name,file_name_len,MSG_NOSIGNAL);

        mysql_free_result(result);

        return 0;
    }

    //如果行数不为0(文件夹内有内容)
    while((row = mysql_fetch_row(result))){
        strcat(file_name,row[0]);
        strcat(file_name," ");
    }
    strcat(file_name,"\n");

    file_name_len = strlen(file_name);
    send(pclient_info->net_fd,&file_name_len,sizeof(int),MSG_NOSIGNAL);
    send(pclient_info->net_fd,file_name,file_name_len,MSG_NOSIGNAL);

    mysql_free_result(result);

    return 0;
}

//服务端cd实现代码
int cd_handler(client_info_t* pclient_info, MYSQL* mysql){
    user_t user;
    select_user(mysql,pclient_info->name,&user);
    int file_id = user.file_id;

    char query[256] = {0};  //用来放SQL语句的字符串
    MYSQL_RES *result;
    MYSQL_ROW row;

    char response[256] = {0};
    int response_len = 0;

    //如果是cd /
    if(strcmp(pclient_info->argument,"/") == 0){
        sprintf(query,"select f.file_id from file f join user u on "
                "f.user_id = u.user_id "
                "where u.file_id = %d and f.file_name = '/'",
                file_id);
        if(mysql_query(mysql,query)){
            fprintf(stderr,"query error:%s\n",mysql_error(mysql));
            return -1;
        }
        //接收处理结果集
        result = mysql_store_result(mysql);
        ERROR_CHECK(result,NULL,"mysql_store_result");
        if(mysql_num_rows(result) == 0){
            fprintf(stderr,"num of rows error\n");
            return -1;
        }
        int dest_id = 0;
        if((row = mysql_fetch_row(result))){
            dest_id = atoi(row[0]);
        }
        //释放结果集
        mysql_free_result(result);
        if(dest_id == 0){
            //未得到预期结果
            return -1;
        }
        //更新user表中的file_id
        bzero(query,sizeof(query));
        sprintf(query,"update user set file_id = %d where user_name = '%s'",
                dest_id,pclient_info->name);
        if(mysql_query(mysql,query)){
            fprintf(stderr,"query error:%s\n",mysql_error(mysql));
            return -1;
        }

        strcpy(response,"成功返回根目录！\n");
        response_len = strlen(response);
        send(pclient_info->net_fd,&response_len,sizeof(int),MSG_NOSIGNAL);
        send(pclient_info->net_fd,response,response_len,MSG_NOSIGNAL);

        return 0;
    }

    //如果是cd ..
    else if(strcmp(pclient_info->argument,"..") == 0){
        sprintf(query,"select parent_id from file where file_id = %d",file_id);
        if(mysql_query(mysql,query)){
            fprintf(stderr,"query error:%s\n",mysql_error(mysql));
            return -1;
        }
        //接收处理结果集
        result = mysql_store_result(mysql);
        ERROR_CHECK(result,NULL,"mysql_store_result");
        if(mysql_num_rows(result) == 0){
            fprintf(stderr,"num of rows error\n");
            return -1;
        }
        int dest_id = 0;
        if((row = mysql_fetch_row(result))){
            dest_id = atoi(row[0]);
        }
        //释放结果集
        mysql_free_result(result);
        if(dest_id == 0){
            //未得到预期结果
            return -1;
        }

        //如果当前已经处于根目录
        if(dest_id == -1){
            strcpy(response,"已经在根目录了，你怎么回事?\n");
            response_len = strlen(response);
            send(pclient_info->net_fd,&response_len,sizeof(int),MSG_NOSIGNAL);
            send(pclient_info->net_fd,response,response_len,MSG_NOSIGNAL);

            return 0;
        }

        //更新user表中的file_id
        bzero(query,sizeof(query));
        sprintf(query,"update user set file_id = %d where user_name = '%s'",
                dest_id,pclient_info->name);
        if(mysql_query(mysql,query)){
            fprintf(stderr,"query error:%s\n",mysql_error(mysql));
            return -1;
        }

        strcpy(response,"成功返回上级目录！\n");
        response_len = strlen(response);
        send(pclient_info->net_fd,&response_len,sizeof(int),MSG_NOSIGNAL);
        send(pclient_info->net_fd,response,response_len,MSG_NOSIGNAL);

        return 0;
    }

    //如果是cd argument,要先判断请求的file_name是否存在
    else{
        sprintf(query,"select file_id from file where parent_id = %d "
                "and file_name = '%s' and file_type = 'd' and cancel_flag = 0",
                file_id,pclient_info->argument);
        if(mysql_query(mysql,query)){
            fprintf(stderr,"query error:%s\n",mysql_error(mysql));
            return -1;
        }
        //接收处理结果集
        result = mysql_store_result(mysql);
        ERROR_CHECK(result,NULL,"mysql_store_result");

        int res_rows = mysql_num_rows(result);
        //该目录不存在
        if(res_rows == 0){
            strcpy(response,"进不去，怎么想都进不去。(该文件不存在或不是目录文件)\n");
            response_len = strlen(response);
            send(pclient_info->net_fd,&response_len,sizeof(int),MSG_NOSIGNAL);
            send(pclient_info->net_fd,response,response_len,MSG_NOSIGNAL);

            return 0;
        }
        int dest_id = 0;
        if((row = mysql_fetch_row(result))){
            dest_id = atoi(row[0]);
        }
        //释放结果集
        mysql_free_result(result);
        if(dest_id == 0){
            //未得到预期结果
            return -1;
        }

        //更新user表中的file_id
        bzero(query,sizeof(query));
        sprintf(query,"update user set file_id = %d where user_name = '%s'",
                dest_id,pclient_info->name);
        if(mysql_query(mysql,query)){
            fprintf(stderr,"query error:%s\n",mysql_error(mysql));
            return -1;
        }

        strcpy(response,"成功打开文件！\n");
        response_len = strlen(response);
        send(pclient_info->net_fd,&response_len,sizeof(int),MSG_NOSIGNAL);
        send(pclient_info->net_fd,response,response_len,MSG_NOSIGNAL);

        return 0;
    }
}

//服务端pwd实现代码
int pwd_handler(client_info_t* pclient_info, MYSQL* mysql){
    user_t user;
    select_user(mysql,pclient_info->name,&user);
    int file_id = user.file_id;

    char query[256] = {0};  //用来放SQL语句的字符串
    MYSQL_RES *result;
    MYSQL_ROW row;

    char file_path[300] = {0};
    int file_path_len = 0;
    strcpy(file_path,"当前所在路径为: ");

    sprintf(query,"select file_path from file where file_id = %d",file_id);
    if(mysql_query(mysql,query)){
        fprintf(stderr,"query error:%s\n",mysql_error(mysql));
        return -1;
    }
    //接收处理结果集
    result = mysql_store_result(mysql);
    ERROR_CHECK(result,NULL,"mysql_store_result");
    if((row = mysql_fetch_row(result))){
        strcat(file_path,row[0]);
    }
    mysql_free_result(result);

    strcat(file_path,"\n");

    file_path_len = strlen(file_path);
    send(pclient_info->net_fd,&file_path_len,sizeof(int),MSG_NOSIGNAL);
    send(pclient_info->net_fd,file_path,file_path_len,MSG_NOSIGNAL);

    return 0;
}

int rm_handler(client_info_t* pclient_info, MYSQL* mysql){
    //传递过来的是非法参数，空字符串或空格字符串
    if(pclient_info->argument[0] == '\0' || pclient_info->argument[0] == ' ')
    {
        send_train("删除失败，非法命令参数！\n", pclient_info->net_fd);
        return -1;
    }
    //切割传递过来的参数
    //定义一个指针数组,用于存储多个参数
    char *argument[100] = { NULL };  
    char str_buf[256];//临时缓冲区，用于存储当前切割的子字符串
    char *argu = strtok(pclient_info->argument," ");//切割了一次
    int i = 0;

    while(argu != NULL && i < 100){
        //将当前字符串复制到临时缓冲区
        strncpy(str_buf, argu, 255);
        //确保字符串以 null 结尾
        str_buf[255] = '\0';
        //为当前子字符串分配内存，并存储到指针数组中
        argument[i] = (char *)calloc(1, (strlen(str_buf) + 1));
        strcpy(argument[i], str_buf);

        //打印当前字符串
        //printf("命令参数 %d 号为: %s \n", i, argument[i]);

        //获取下一个子字符串
        argu = strtok(NULL, " ");
        i++;
    }
    //num_argu为参数的总数量 
    int num_argu = i;
    user_t user_table;
    bzero(&user_table, sizeof(user_table));
    //获取当前用户的对应的file_id
    int file_id = select_user(mysql, pclient_info->name, &user_table);
    if(file_id == -1)
    {
        printf("获取用户 %s 的对应的fileid失败 \n",pclient_info->name);
    }
    for(int j = 0;j < num_argu; j++){
        /////////实现删除单个文件或目录////////
        //判断是否删除的是根目录
        char query[2048] = {0};
        sprintf(query, "select file_id from file where parent_id = %d and file_name = '%s' and user_id = %d  and cancel_flag = 0 ",
                user_table.file_id, argument[j], user_table.user_id);
        if( mysql_query(mysql,query)){
            printf("mysql_error: %s \n", mysql_error(mysql));

        }
        //printf("mysql_error: %s \n", mysql_error(mysql));

        //获取查询的结果
        MYSQL_RES *result = mysql_store_result(mysql);
        //printf("mysql_error: %s \n", mysql_error(mysql));
        //若查询的结果为空，返回的结果可能为NULL，也可能为非NULL，说明要删除的文件不存在，报错
        if(result == NULL){
            char file[100] = {0};
            sprintf(file," %s 文件无法删除,因为不存在 \n" , argument[j]);
            send_train(file, pclient_info->net_fd);
            mysql_free_result(result);          
            continue;
        }
        if(mysql_num_rows(result) == 0){
            char file[100] = {0};
            sprintf(file," %s 文件无法删除,因为不存在 \n" , argument[j]);
            send_train(file, pclient_info->net_fd);
            mysql_free_result(result);          
            continue;
        }

        //若删除的文件存在
        MYSQL_ROW row;
        row = mysql_fetch_row(result);
        memset(query, 0, 2048);
        int file_id_m = atoi(row[0]);
        sprintf(query, "update file set cancel_flag = 1 where file_id = %d ",file_id_m );
        mysql_query(mysql,query);
        char file[100] = {0};
        sprintf(file," %s 文件删除成功 \n" , argument[j]);
        send_train(file, pclient_info->net_fd);
        //printf("mysql_error: %s \n", mysql_error(mysql));
        mysql_free_result(result);          
    }
    return 0;
}
int mkdir_handler(client_info_t* pclient_info, MYSQL* mysql){
    printf("net_fd = %d\n",pclient_info->net_fd);
    puts(pclient_info->name);
    puts(pclient_info->command);
    puts(pclient_info->argument);

    user_t user_info;
    memset(&user_info, 0, sizeof(user_info));
    select_user(mysql, pclient_info->name, &user_info);

    //确定创建一个文件夹的必要参数用于构建sql语句
    //首先取出要创建的目录的名称
    char* file_name = pclient_info->argument;

    if(strlen(file_name) == 0){
        char err_msg[4096] = { 0 };
        sprintf(err_msg, "缺少操作对象，请指定目录的名称\n");

        int errmsg_len = strlen(err_msg);
        send(pclient_info->net_fd, &errmsg_len, sizeof(int), MSG_NOSIGNAL);
        send(pclient_info->net_fd, err_msg, errmsg_len, MSG_NOSIGNAL);

        printf("%s\n", err_msg);
        return 0;

    }

    //不允许创建含有空格的目录和斜杠
    for(unsigned long i = 0; i < strlen(file_name); i++){
        if(file_name[i] == ' ' || file_name[i] == '/'){
            char err_msg[4096] = { 0 };
            sprintf(err_msg, "不允许创建名称中含有空格或斜杠的目录\n");

            int errmsg_len = strlen(err_msg);
            send(pclient_info->net_fd, &errmsg_len, sizeof(int), MSG_NOSIGNAL);
            send(pclient_info->net_fd, err_msg, errmsg_len, MSG_NOSIGNAL);

            printf("%s\n", err_msg);
            return 0;
        }
    }

    if(strcmp(file_name, ".") == 0 || strcmp(file_name, "..") == 0){
        char err_msg[4096] = { 0 };
        sprintf(err_msg, "该目录名称已被系统占用\n");

        int errmsg_len = strlen(err_msg);
        send(pclient_info->net_fd, &errmsg_len, sizeof(int), MSG_NOSIGNAL);
        send(pclient_info->net_fd, err_msg, errmsg_len, MSG_NOSIGNAL);

        printf("%s\n", err_msg);
        return 0;
    }

    //判断该名称是否和已存在的目录重名，若是则返回-1，创建失败
    char query[4096] = { 0 };
    memset(query, 0, sizeof(query));
    sprintf(query, "select file_name, cancel_flag from file where parent_id = %d", user_info.file_id);
    mysql_query(mysql, query);
    MYSQL_RES* result = mysql_store_result(mysql);
    int row_size = mysql_num_rows(result);

    for(int i = 0; i < row_size; i++){
        MYSQL_ROW row = mysql_fetch_row(result);

        if(strcmp(row[0], file_name) == 0 && atoi(row[1]) == 0){
            char err_msg[4096] = { 0 };
            sprintf(err_msg, "无法创建目录%s：文件已存在\n", file_name);

            int errmsg_len = strlen(err_msg);
            send(pclient_info->net_fd, &errmsg_len, sizeof(int), MSG_NOSIGNAL);
            send(pclient_info->net_fd, err_msg, errmsg_len, MSG_NOSIGNAL);

            printf("无法创建目录%s：文件已存在\n", file_name);
            return 0;
        }
    }

    //若函数执行到此处仍未返回，表明可以创建目录

    //根据用户当前所在路径的id到file表中查找其当前路径的字符串用于拼接
    memset(query, 0, sizeof(query));
    sprintf(query, "select file_path from file where file_id = %d", user_info.file_id);
    mysql_query(mysql, query);
    MYSQL_RES* result_2 = mysql_store_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(result_2);

    //file_path用于存储新建的目录的路径字符串
    char file_path[4096] = { 0 };
    strcpy(file_path, row[0]);

    //根据user_info.user_id到file表中查找parent_id
    memset(query, 0, sizeof(query));
    sprintf(query, "select parent_id from file where file_id = %d", user_info.file_id);
    mysql_query(mysql, query);
    MYSQL_RES* result_3 = mysql_store_result(mysql);

    MYSQL_ROW row_2 = mysql_fetch_row(result_3);
    int curr_parent_id = atoi(row_2[0]);

    if(curr_parent_id != -1){
        strcat(file_path, "/");
    }

    strcat(file_path, pclient_info->argument);

    //parent_id用于存储新建的目录的父目录的id
    int parent_id = user_info.file_id;

    //user_id用于存储新建的目录的拥有者
    int user_id = user_info.user_id;

    //file_type用于指定新建的目录的文件类型
    char* file_type = "d";

    //cancel_flag用于指示文件的删除标记
    int cancel_flag = 0;

    //bad_file指示文件是否处于损坏状态
    int bad_file = 0;

    //构建最终用于新建目录的sql语句
    char mkdir_sql[8192] = { 0 };

    sprintf(mkdir_sql, "insert into file values(NULL, %d, '%s', %d, NULL, '%s', '%s', %d, %d)", 
            parent_id, file_name, user_id, file_type, file_path, cancel_flag, bad_file);

    //执行新建目录的语句
    mysql_query(mysql, mkdir_sql);

    char* msg = "创建新目录成功\n";
    int msg_len = strlen(msg);
    send(pclient_info->net_fd, &msg_len, sizeof(int), MSG_NOSIGNAL);
    send(pclient_info->net_fd, msg, msg_len, MSG_NOSIGNAL);

    printf("创建新目录成功\n");

    //释放资源并关闭连接
    mysql_free_result(result);
    mysql_free_result(result_2);

    return 0;
}
